<template>
  <div class="form-designer">
    <div class="designer-container">
      <!-- 左侧：组件面板 -->
      <div class="widget-panel">
        <h3>组件库</h3>
        <el-collapse v-model="activeCollapse" accordion>
          <!-- 基础字段 -->
          <el-collapse-item title="基础字段" name="basic">
            <draggable
              :list="basicWidgets"
              :group="{ name: 'widgets', pull: 'clone', put: false }"
              :clone="cloneWidget"
              :sort="false"
              class="widget-list"
            >
              <div
                v-for="widget in basicWidgets"
                :key="widget.type"
                class="widget-item"
              >
                <i :class="widget.icon"></i>
                <span>{{ widget.label }}</span>
              </div>
            </draggable>
          </el-collapse-item>

          <!-- 高级字段 -->
          <el-collapse-item title="高级字段" name="advanced">
            <draggable
              :list="advancedWidgets"
              :group="{ name: 'widgets', pull: 'clone', put: false }"
              :clone="cloneWidget"
              :sort="false"
              class="widget-list"
            >
              <div
                v-for="widget in advancedWidgets"
                :key="widget.type"
                class="widget-item"
              >
                <i :class="widget.icon"></i>
                <span>{{ widget.label }}</span>
              </div>
            </draggable>
          </el-collapse-item>

          <!-- 布局组件 -->
          <el-collapse-item title="布局组件" name="layout">
            <draggable
              :list="layoutWidgets"
              :group="{ name: 'widgets', pull: 'clone', put: false }"
              :clone="cloneWidget"
              :sort="false"
              class="widget-list"
            >
              <div
                v-for="widget in layoutWidgets"
                :key="widget.type"
                class="widget-item"
              >
                <i :class="widget.icon"></i>
                <span>{{ widget.label }}</span>
              </div>
            </draggable>
          </el-collapse-item>
        </el-collapse>
      </div>

      <!-- 中间：画布区域 -->
      <div class="canvas-panel">
        <div class="canvas-header">
          <h3>表单设计</h3>
          <div class="canvas-actions">
            <el-button size="small" @click="previewForm">
              <i class="el-icon-view"></i> 预览
            </el-button>
            <el-button size="small" @click="clearForm">
              <i class="el-icon-delete"></i> 清空
            </el-button>
            <el-button size="small" type="primary" @click="saveForm">
              <i class="el-icon-check"></i> 保存
            </el-button>
          </div>
        </div>
        <div class="canvas-body">
          <el-form
            :model="formModel"
            label-width="100px"
            class="design-form"
          >
            <draggable
              v-model="formItems"
              group="widgets"
              :animation="200"
              handle=".drag-handle"
              class="form-canvas"
              :class="{ 'is-empty': formItems.length === 0 }"
            >
              <div
                v-for="(item, index) in formItems"
                :key="item.key"
                class="form-item-wrapper"
                :class="{ 'is-active': activeItem === item }"
                @click.stop="selectItem(item)"
              >
                <div class="form-item-header">
                  <i class="el-icon-rank drag-handle"></i>
                  <span class="item-label">{{ item.label }}</span>
                  <el-button
                    type="text"
                    size="mini"
                    icon="el-icon-delete"
                    @click.stop="deleteItem(index)"
                  ></el-button>
                </div>
                <el-form-item :label="item.label" :required="item.required">
                  <component
                    :is="getComponentType(item.type)"
                    v-model="formModel[item.key]"
                    v-bind="getComponentProps(item)"
                    :placeholder="item.placeholder"
                    :disabled="true"
                  >
                    <template v-if="item.type === 'select' || item.type === 'radio' || item.type === 'checkbox'">
                      <el-option
                        v-for="option in item.options"
                        :key="option.value"
                        :label="option.label"
                        :value="option.value"
                      ></el-option>
                    </template>
                    <template v-if="item.type === 'radio'">
                      <el-radio
                        v-for="option in item.options"
                        :key="option.value"
                        :label="option.value"
                      >{{ option.label }}</el-radio>
                    </template>
                    <template v-if="item.type === 'checkbox'">
                      <el-checkbox
                        v-for="option in item.options"
                        :key="option.value"
                        :label="option.value"
                      >{{ option.label }}</el-checkbox>
                    </template>
                  </component>
                </el-form-item>
              </div>
              <div v-if="formItems.length === 0" class="empty-canvas">
                <i class="el-icon-plus"></i>
                <p>拖拽左侧组件到此处</p>
              </div>
            </draggable>
          </el-form>
        </div>
      </div>

      <!-- 右侧：属性配置面板 -->
      <div class="config-panel">
        <h3>组件属性</h3>
        <div v-if="activeItem" class="config-form">
          <el-form label-width="80px" size="small">
            <el-form-item label="字段标签">
              <el-input v-model="activeItem.label"></el-input>
            </el-form-item>
            <el-form-item label="字段名称">
              <el-input v-model="activeItem.key"></el-input>
            </el-form-item>
            <el-form-item label="占位提示">
              <el-input v-model="activeItem.placeholder"></el-input>
            </el-form-item>
            <el-form-item label="是否必填">
              <el-switch v-model="activeItem.required"></el-switch>
            </el-form-item>
            <el-form-item label="默认值" v-if="activeItem.type !== 'file'">
              <el-input v-model="activeItem.defaultValue"></el-input>
            </el-form-item>
            
            <!-- 选项配置 -->
            <el-form-item 
              label="选项配置" 
              v-if="['select', 'radio', 'checkbox'].includes(activeItem.type)"
            >
              <div class="options-config">
                <div
                  v-for="(option, index) in activeItem.options"
                  :key="index"
                  class="option-item"
                >
                  <el-input
                    v-model="option.label"
                    placeholder="选项名称"
                    size="mini"
                  ></el-input>
                  <el-input
                    v-model="option.value"
                    placeholder="选项值"
                    size="mini"
                    style="margin-left: 10px;"
                  ></el-input>
                  <el-button
                    type="text"
                    icon="el-icon-delete"
                    size="mini"
                    @click="deleteOption(index)"
                  ></el-button>
                </div>
                <el-button
                  size="small"
                  type="text"
                  icon="el-icon-plus"
                  @click="addOption"
                >添加选项</el-button>
              </div>
            </el-form-item>

            <!-- 多行文本配置 -->
            <el-form-item label="行数" v-if="activeItem.type === 'textarea'">
              <el-input-number v-model="activeItem.rows" :min="2" :max="10"></el-input-number>
            </el-form-item>

            <!-- 数字输入配置 -->
            <template v-if="activeItem.type === 'number'">
              <el-form-item label="最小值">
                <el-input-number v-model="activeItem.min"></el-input-number>
              </el-form-item>
              <el-form-item label="最大值">
                <el-input-number v-model="activeItem.max"></el-input-number>
              </el-form-item>
              <el-form-item label="步长">
                <el-input-number v-model="activeItem.step" :min="1"></el-input-number>
              </el-form-item>
            </template>
          </el-form>
        </div>
        <div v-else class="empty-config">
          <i class="el-icon-info"></i>
          <p>请选择一个组件</p>
        </div>
      </div>
    </div>

    <!-- 预览对话框 -->
    <el-dialog 
      title="表单预览" 
      :visible.sync="previewVisible" 
      width="60%"
      append-to-body
      :modal-append-to-body="true"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <div v-if="formItems.length === 0" class="preview-empty">
        <i class="el-icon-warning"></i>
        <p>表单中还没有添加任何组件</p>
      </div>
      <el-form v-else :model="previewModel" label-width="120px">
        <el-form-item
          v-for="item in formItems"
          :key="item.key"
          :label="item.label"
          :required="item.required"
        >
          <component
            :is="getComponentType(item.type)"
            v-model="previewModel[item.key]"
            v-bind="getComponentProps(item)"
            :placeholder="item.placeholder"
          >
            <template v-if="item.type === 'select'">
              <el-option
                v-for="option in item.options"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              ></el-option>
            </template>
            <template v-if="item.type === 'radio'">
              <el-radio
                v-for="option in item.options"
                :key="option.value"
                :label="option.value"
              >{{ option.label }}</el-radio>
            </template>
            <template v-if="item.type === 'checkbox'">
              <el-checkbox
                v-for="option in item.options"
                :key="option.value"
                :label="option.value"
              >{{ option.label }}</el-checkbox>
            </template>
          </component>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="previewVisible = false">关闭</el-button>
        <el-button type="primary" @click="previewVisible = false">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  name: 'FormDesigner',
  components: {
    draggable
  },
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      activeCollapse: 'basic',
      formItems: [],
      formModel: {},
      activeItem: null,
      previewVisible: false,
      previewModel: {},
      widgetIdCounter: 0,
      
      // 基础字段组件
      basicWidgets: [
        { type: 'input', label: '单行文本', icon: 'el-icon-edit' },
        { type: 'textarea', label: '多行文本', icon: 'el-icon-document' },
        { type: 'number', label: '数字输入', icon: 'el-icon-s-data' },
        { type: 'select', label: '下拉选择', icon: 'el-icon-arrow-down' },
        { type: 'radio', label: '单选框', icon: 'el-icon-success' },
        { type: 'checkbox', label: '多选框', icon: 'el-icon-finished' },
        { type: 'date', label: '日期选择', icon: 'el-icon-date' },
        { type: 'time', label: '时间选择', icon: 'el-icon-time' }
      ],
      
      // 高级字段组件
      advancedWidgets: [
        { type: 'daterange', label: '日期范围', icon: 'el-icon-date' },
        { type: 'file', label: '文件上传', icon: 'el-icon-upload' },
        { type: 'rate', label: '评分', icon: 'el-icon-star-off' },
        { type: 'slider', label: '滑块', icon: 'el-icon-minus' },
        { type: 'switch', label: '开关', icon: 'el-icon-open' }
      ],
      
      // 布局组件
      layoutWidgets: [
        { type: 'divider', label: '分割线', icon: 'el-icon-minus' },
        { type: 'text', label: '文本说明', icon: 'el-icon-document' }
      ]
    }
  },
  
  watch: {
    formItems: {
      handler() {
        this.emitChange()
      },
      deep: true
    },
    value: {
      handler(val) {
        if (val && val !== this.getFormConfig()) {
          this.loadFormConfig(val)
        }
      },
      immediate: true
    }
  },
  
  methods: {
    // 克隆组件
    cloneWidget(widget) {
      const id = ++this.widgetIdCounter
      const newWidget = {
        ...widget,
        key: `field_${id}`,
        label: widget.label,
        placeholder: `请输入${widget.label}`,
        required: false,
        defaultValue: '',
        options: ['select', 'radio', 'checkbox'].includes(widget.type) 
          ? [
              { label: '选项1', value: '1' },
              { label: '选项2', value: '2' }
            ]
          : undefined,
        rows: widget.type === 'textarea' ? 3 : undefined,
        min: widget.type === 'number' ? 0 : undefined,
        max: widget.type === 'number' ? 100 : undefined,
        step: widget.type === 'number' ? 1 : undefined
      }
      return newWidget
    },
    
    // 选择组件
    selectItem(item) {
      this.activeItem = item
    },
    
    // 删除组件
    deleteItem(index) {
      if (this.formItems[index] === this.activeItem) {
        this.activeItem = null
      }
      this.formItems.splice(index, 1)
    },
    
    // 添加选项
    addOption() {
      if (!this.activeItem.options) {
        this.$set(this.activeItem, 'options', [])
      }
      this.activeItem.options.push({
        label: `选项${this.activeItem.options.length + 1}`,
        value: String(this.activeItem.options.length + 1)
      })
    },
    
    // 删除选项
    deleteOption(index) {
      this.activeItem.options.splice(index, 1)
    },
    
    // 获取组件类型
    getComponentType(type) {
      const typeMap = {
        input: 'el-input',
        textarea: 'el-input',
        number: 'el-input-number',
        select: 'el-select',
        radio: 'el-radio-group',
        checkbox: 'el-checkbox-group',
        date: 'el-date-picker',
        time: 'el-time-picker',
        daterange: 'el-date-picker',
        file: 'el-upload',
        rate: 'el-rate',
        slider: 'el-slider',
        switch: 'el-switch'
      }
      return typeMap[type] || 'el-input'
    },
    
    // 获取组件属性
    getComponentProps(item) {
      const props = {}
      
      if (item.type === 'textarea') {
        props.type = 'textarea'
        props.rows = item.rows || 3
      }
      
      if (item.type === 'number') {
        props.min = item.min
        props.max = item.max
        props.step = item.step
      }
      
      if (item.type === 'date') {
        props.type = 'date'
        props.valueFormat = 'yyyy-MM-dd'
      }
      
      if (item.type === 'daterange') {
        props.type = 'daterange'
        props.valueFormat = 'yyyy-MM-dd'
        props.rangeSeparator = '至'
        props.startPlaceholder = '开始日期'
        props.endPlaceholder = '结束日期'
      }
      
      if (item.type === 'time') {
        props.valueFormat = 'HH:mm:ss'
      }
      
      return props
    },
    
    // 预览表单
    previewForm() {
      this.previewModel = {}
      this.previewVisible = true
    },
    
    // 清空表单
    clearForm() {
      this.$confirm('确定要清空表单吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.formItems = []
        this.activeItem = null
        this.$message.success('已清空')
      }).catch(() => {})
    },
    
    // 保存表单
    saveForm() {
      this.$emit('save', this.getFormConfig())
    },
    
    // 获取表单配置
    getFormConfig() {
      return JSON.stringify(this.formItems)
    },
    
    // 加载表单配置
    loadFormConfig(config) {
      try {
        const items = JSON.parse(config)
        this.formItems = items || []
        this.activeItem = null
      } catch (e) {
        console.error('加载表单配置失败:', e)
      }
    },
    
    // 触发change事件
    emitChange() {
      this.$emit('input', this.getFormConfig())
      this.$emit('change', this.getFormConfig())
    }
  }
}
</script>

<style scoped>
.form-designer {
  height: calc(100vh - 200px);
  background: #f0f2f5;
}

.form-designer .designer-container {
  display: flex;
  height: 100%;
}

/* 左侧组件面板 */
.form-designer .widget-panel {
  width: 260px;
  background: #fff;
  border-right: 1px solid #e6e6e6;
  overflow-y: auto;
}

.form-designer .widget-panel h3 {
  padding: 15px;
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  border-bottom: 1px solid #e6e6e6;
}

.form-designer .widget-list {
  padding: 10px;
  min-height: 100px;
}

.form-designer .widget-item {
  display: flex;
  align-items: center;
  padding: 10px;
  margin-bottom: 8px;
  background: #f5f7fa;
  border: 1px solid #e6e6e6;
  border-radius: 4px;
  cursor: move;
  transition: all 0.3s;
}

.form-designer .widget-item:hover {
  background: #ecf5ff;
  border-color: #409eff;
  color: #409eff;
}

.form-designer .widget-item i {
  margin-right: 8px;
  font-size: 16px;
}

.form-designer .widget-item span {
  font-size: 13px;
}

/* 中间画布区域 */
.form-designer .canvas-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
  margin: 0 10px;
}

.form-designer .canvas-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  border-bottom: 1px solid #e6e6e6;
}

.form-designer .canvas-header h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.form-designer .canvas-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.form-designer .design-form {
  min-height: 400px;
}

.form-designer .form-canvas {
  min-height: 400px;
}

.form-designer .form-canvas.is-empty {
  border: 2px dashed #d9d9d9;
  border-radius: 4px;
}

.form-designer .empty-canvas {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 400px;
  color: #999;
}

.form-designer .empty-canvas i {
  font-size: 48px;
  margin-bottom: 10px;
}

.form-designer .form-item-wrapper {
  position: relative;
  margin-bottom: 15px;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 4px;
  transition: all 0.3s;
}

.form-designer .form-item-wrapper:hover {
  background: #f5f7fa;
  border-color: #e6e6e6;
}

.form-designer .form-item-wrapper.is-active {
  background: #ecf5ff;
  border-color: #409eff;
}

.form-designer .form-item-header {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.form-designer .drag-handle {
  cursor: move;
  margin-right: 8px;
  color: #999;
}

.form-designer .item-label {
  flex: 1;
  font-size: 12px;
  color: #666;
}

/* 右侧属性配置面板 */
.form-designer .config-panel {
  width: 300px;
  background: #fff;
  border-left: 1px solid #e6e6e6;
  overflow-y: auto;
}

.form-designer .config-panel h3 {
  padding: 15px;
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  border-bottom: 1px solid #e6e6e6;
}

.form-designer .config-form {
  padding: 15px;
}

.form-designer .empty-config {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #999;
}

.form-designer .empty-config i {
  font-size: 48px;
  margin-bottom: 10px;
}

.form-designer .options-config .option-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

/* 预览对话框空状态 */
.preview-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  color: #999;
}

.preview-empty i {
  font-size: 64px;
  color: #e6a23c;
  margin-bottom: 16px;
}

.preview-empty p {
  font-size: 14px;
  margin: 0;
}
</style>

